package com.boot.unity.api.utils;

import com.boot.unity.api.common.wrapper.CustomRequestWrapper;
import com.boot.unity.api.constants.Constants;
import com.boot.unity.api.constants.EncryptEnum;
import com.boot.unity.api.modules.cert.entity.Cert;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
public class SignUtil {

    public static boolean validateSign(HttpServletRequest request, RedisTemplate<String,Cert> redisTemplate) {
        CustomRequestWrapper requestWrapper = (CustomRequestWrapper) request;

        String data = requestWrapper.getBody();
        log.error("data:{}",data);

        String version = request.getParameter(Constants.VERSION_KEY);
        String timestamp = request.getParameter(Constants.TIMESTAMP_KEY);
        String sign = request.getParameter(Constants.SIGN_KEY);
        String appId = request.getParameter(Constants.USER_KEY);

        String appIdKey = Constants.APPID_KEY+appId;
        Cert cert = redisTemplate.boundValueOps(appIdKey).get();
        if ((cert == null) || (StringUtils.isBlank(cert.getAppSecret()))){
            return false;
        }
        if (StringUtils.countMatches(version,".") != 3){
            return false;
        }
        String[] versionSplit = version.split("\\.");
        if (versionSplit.length != 4){
            return false;
        }
        String encryptType = versionSplit[3];
        EncryptEnum encrypt = EncryptEnum.getEncryptType(encryptType);
        if (encrypt == null){
            return false;
        }
        String sequence = data+timestamp+cert.getAppSecret();
        String compareSign;
        switch (encrypt){
            case E1:
                compareSign = DigestUtils.sha1Hex(sequence);
                break;
            case E2:
                compareSign = DigestUtils.sha256Hex(sequence);
                break;
            case E3:
                compareSign = DigestUtils.sha512Hex(sequence);
                break;
            default:
                return false;
        }
        log.error("sign:{}",sign);
        log.error("compareSign:{}",compareSign);
        return StringUtils.equals(sign, compareSign);
    }

    public static boolean validateSign2(HttpServletRequest request) {
        String requestSign = request.getParameter("sign");//获得请求签名，如sign=19e907700db7ad91318424a97c54ed57
        if (StringUtils.isEmpty(requestSign)) {
            return false;
        }
        List<String> keys = new ArrayList<String>(request.getParameterMap().keySet());
        keys.remove("sign");//排除sign参数
        Collections.sort(keys);//排序

        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            sb.append(key).append("=").append(request.getParameter(key)).append("&");//拼接字符串
        }
        String linkString = sb.toString();
        linkString = StringUtils.substring(linkString, 0, linkString.length() - 1);//去除最后一个'&'

        String secret = "Potato";//密钥
        String sign = DigestUtils.md5Hex(linkString + secret);//混合密钥md5

        return StringUtils.equals(sign, requestSign);//比较
    }
}
